const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const UserModel = require('../models/user.model');

class UserService {
  /**
   * 创建新用户
   * @param {Object} userData - 用户数据
   * @returns {Promise<Object>} 创建的用户信息
   */
  static async createUser(userData) {
    const { username, password, email, fullName, role, phone, department } = userData;
    
    // 检查用户名是否已存在
    const existingUser = await UserModel.findByUsername(username);
    if (existingUser) {
      throw new Error('用户名已存在');
    }
    
    // 密码加密
    const saltRounds = 12;
    const hashedPassword = await bcrypt.hash(password, saltRounds);
    
    // 创建用户
    const newUser = await UserModel.create({
      username,
      password: hashedPassword,
      email,
      fullName,
      role,
      phone,
      department
    });
    
    return newUser;
  }

  /**
   * 用户登录
   * @param {string} username - 用户名
   * @param {string} password - 密码
   * @returns {Promise<Object>} 登录结果
   */
  static async loginUser(username, password) {
    // 查找用户
    const user = await UserModel.findByUsername(username);
    if (!user) {
      throw new Error('用户名或密码错误');
    }
    
    // 验证密码
    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      throw new Error('用户名或密码错误');
    }
    
    // 更新最后登录时间
    await UserModel.updateLastLogin(user.id);
    
    // 生成JWT令牌
    const token = jwt.sign(
      { 
        userId: user.id, 
        username: user.username, 
        role: user.role 
      },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES_IN || '24h' }
    );
    
    // 返回用户信息（不包含密码）
    const { password: _, ...userInfo } = user;
    
    return {
      user: userInfo,
      token
    };
  }

  /**
   * 获取所有用户
   * @param {Object} filters - 筛选条件
   * @returns {Promise<Object>} 用户列表
   */
  static async getAllUsers(filters) {
    return await UserModel.findAll(filters);
  }

  /**
   * 根据ID查找用户
   * @param {number} id - 用户ID
   * @returns {Promise<Object|null>} 用户信息
   */
  static async findUserById(id) {
    const user = await UserModel.findById(id);
    if (!user) {
      throw new Error('用户不存在');
    }
    return user;
  }

  /**
   * 更新用户信息
   * @param {number} id - 用户ID
   * @param {Object} updateData - 更新数据
   * @returns {Promise<Object>} 更新后的用户信息
   */
  static async updateUser(id, updateData) {
    // 检查用户是否存在
    const existingUser = await UserModel.findById(id);
    if (!existingUser) {
      throw new Error('用户不存在');
    }
    
    // 如果更新用户名，检查是否重复
    if (updateData.username && updateData.username !== existingUser.username) {
      const userWithSameUsername = await UserModel.findByUsername(updateData.username);
      if (userWithSameUsername) {
        throw new Error('用户名已存在');
      }
    }
    
    // 如果更新密码，进行加密
    if (updateData.password) {
      const saltRounds = 12;
      updateData.password = await bcrypt.hash(updateData.password, saltRounds);
    }
    
    // 更新用户
    const success = await UserModel.update(id, updateData);
    if (!success) {
      throw new Error('更新用户失败');
    }
    
    // 返回更新后的用户信息
    return await UserModel.findById(id);
  }

  /**
   * 删除用户
   * @param {number} id - 用户ID
   * @returns {Promise<boolean>} 删除是否成功
   */
  static async deleteUser(id) {
    // 检查用户是否存在
    const existingUser = await UserModel.findById(id);
    if (!existingUser) {
      throw new Error('用户不存在');
    }
    
    // 删除用户
    const success = await UserModel.remove(id);
    if (!success) {
      throw new Error('删除用户失败');
    }
    
    return true;
  }

  /**
   * 修改密码
   * @param {number} userId - 用户ID
   * @param {string} oldPassword - 旧密码
   * @param {string} newPassword - 新密码
   * @returns {Promise<boolean>} 修改是否成功
   */
  static async changePassword(userId, oldPassword, newPassword) {
    // 获取用户信息（包含密码）
    const user = await UserModel.findByUsername(
      (await UserModel.findById(userId)).username
    );
    
    if (!user) {
      throw new Error('用户不存在');
    }
    
    // 验证旧密码
    const isOldPasswordValid = await bcrypt.compare(oldPassword, user.password);
    if (!isOldPasswordValid) {
      throw new Error('旧密码错误');
    }
    
    // 加密新密码
    const saltRounds = 12;
    const hashedNewPassword = await bcrypt.hash(newPassword, saltRounds);
    
    // 更新密码
    const success = await UserModel.update(userId, { password: hashedNewPassword });
    if (!success) {
      throw new Error('修改密码失败');
    }
    
    return true;
  }
}

module.exports = UserService;